package com.twb.quartz.service.impl;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.twb.core.base.entity.TwbPageInfo;
import com.twb.core.base.service.impl.BaseService;
import com.twb.core.exception.ServiceException;
import com.twb.core.util.BeanUtils;
import com.twb.core.util.ExcelUtils;
import com.twb.core.util.TwbPageUtil;
import com.twb.quartz.constants.QuartzConstants;
import com.twb.quartz.entity.twbQuartzJob.TwbQuartzJob;
import com.twb.quartz.entity.twbQuartzJob.dto.ExportExcelTwbQuartzJobDto;
import com.twb.quartz.entity.twbQuartzJob.dto.SearchTwbQuartzJobDto;
import com.twb.quartz.entity.twbQuartzJob.vo.SaveTwbQuartzJobVo;
import com.twb.quartz.entity.twbQuartzJob.vo.SearchTwbQuartzJobVo;
import com.twb.quartz.entity.twbQuartzJob.vo.UpdateTwbQuartzJobByIdVo;
import com.twb.quartz.mapper.TwbQuartzJobMapper;
import com.twb.quartz.service.ITwbQuartzJobService;
import com.twb.quartz.util.CronUtils;
import com.twb.quartz.util.ScheduleUtils;

/**
 * @ClassName TwbQuartzJobService
 * @Description 定时任务service
 * 
 * @author DSY
 * @date 2021-12-26 10:46:41
 */
@Service("twbQuartzJobService")
public class TwbQuartzJobService extends BaseService<TwbQuartzJobMapper, TwbQuartzJob> implements ITwbQuartzJobService {

	@Autowired
	private Scheduler scheduler;

	@Autowired
	TwbQuartzJobMapper twbQuartzJobMapper;

	@Override
	public TwbPageInfo<SearchTwbQuartzJobDto> searchTwbQuartzJob(SearchTwbQuartzJobVo vo) {
		TwbPageUtil.startPage(vo);
		List<SearchTwbQuartzJobDto> list = twbQuartzJobMapper.searchTwbQuartzJob(vo);
		return TwbPageUtil.of(list);
	}

	@Override
	public List<SearchTwbQuartzJobDto> searchTwbQuartzJobList(SearchTwbQuartzJobVo vo) {
		List<SearchTwbQuartzJobDto> list = twbQuartzJobMapper.searchTwbQuartzJob(vo);
		return list;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveTwbQuartzJob(SaveTwbQuartzJobVo vo) throws SchedulerException {

		TwbQuartzJob checkVo = new TwbQuartzJob();
		checkVo.setCode(vo.getCode()); // 此处需要修改为需要校验重复的字段
		checkVo.setIsdel(0);
		long count = this.count(checkVo);
		if (count > 0) {
			throw new ServiceException(String.format("[%s]已存在", checkVo.getName()));
		}

		TwbQuartzJob record = new TwbQuartzJob();
		BeanUtils.copyNotNullProperties(vo, record);
		record.setId(this.getUUID());
		this.setCreateInfo(record);
		this.setUpdateInfo(record);
		record.setStatus(QuartzConstants.Status.PAUSE.getValue());
		boolean result = this.save(record);
		if (result) {
			ScheduleUtils.createScheduleJob(scheduler, record);
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateTwbQuartzJobById(UpdateTwbQuartzJobByIdVo vo) throws SchedulerException {
		TwbQuartzJob record = twbQuartzJobMapper.selectById(vo.getId());
		if (null == record) {
			throw new ServiceException("数据不存在");
		}

		if (!vo.getName().equalsIgnoreCase(record.getName())) {
			TwbQuartzJob checkVo = new TwbQuartzJob();
			checkVo.setName(vo.getName()); // 此处需要修改为需要校验重复的字段
			checkVo.setIsdel(0);
			long count = this.count(checkVo);
			if (count > 0) {
				throw new ServiceException(String.format("[%s]已存在", checkVo.getName()));
			}
		}

		BeanUtils.copyNotNullProperties(vo, record);
		this.setUpdateInfo(record);
		boolean result = this.updateById(record);
		if (result) {
			JobKey jobKey = ScheduleUtils.getJobKey(record.getId(), record.getGroupName());
			if(scheduler.checkExists(jobKey)) {
				scheduler.deleteJob(jobKey);
			}
			ScheduleUtils.createScheduleJob(scheduler, record);
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteTwbQuartzJobById(String id) throws SchedulerException {
		TwbQuartzJob job = this.getById(id);
		if(job == null) {
			throw new ServiceException("任务不存在");
		}
		boolean result = this.removeById(id);
		if (result) {
			scheduler.deleteJob(ScheduleUtils.getJobKey(id, job.getGroupName()));
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int deleteTwbQuartzJobByIds(String ids) throws SchedulerException {
		String[] idsArray = ids.split(",");
		int rows = 0;
		for (String id : idsArray) {
			boolean result = this.deleteTwbQuartzJobById(id);
			if(result) {
				rows ++;
			}
		}
		return rows;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void exportExcel(SearchTwbQuartzJobVo vo, HttpServletResponse response) throws Exception {
		List<ExportExcelTwbQuartzJobDto> list = twbQuartzJobMapper.searchExportTwbQuartzJob(vo);
		ExcelUtils.exportExcel("定时任务", list, ExportExcelTwbQuartzJobDto.class, response);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int importExcel(Map<String, String> map) {
		System.out.println(map.toString());
		return 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean pauseJob(String id) throws SchedulerException {
		TwbQuartzJob job = this.getById(id);
		if(job == null) {
			throw new ServiceException("任务不存在");
		}
		job.setStatus(QuartzConstants.Status.PAUSE.getValue());
		boolean result = this.updateById(job);
		if(result) {
			scheduler.pauseJob(ScheduleUtils.getJobKey(id, job.getGroupName()));
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean resumeJob(String id) throws SchedulerException {
		TwbQuartzJob job = this.getById(id);
		if(job == null) {
			throw new ServiceException("任务不存在");
		}
		job.setStatus(QuartzConstants.Status.NORMAL.getValue());
		boolean result = this.updateById(job);
		if(result) {
			scheduler.resumeJob(ScheduleUtils.getJobKey(id, job.getGroupName()));
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean chageStatus(String id,String status) throws SchedulerException {
		boolean result = false;
		if(QuartzConstants.Status.NORMAL.getValue().equals(status)) {
			result = resumeJob(id);
		}else {
			result = pauseJob(id);
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void runJob(String id) throws SchedulerException {
		TwbQuartzJob job = this.getById(id);
		if(job == null) {
			throw new ServiceException("任务不存在");
		}
		JobDataMap dataMap = new JobDataMap();
		dataMap.put(QuartzConstants.TASK_PROPERTIES, job);
		scheduler.triggerJob(ScheduleUtils.getJobKey(id, job.getGroupName()),dataMap);
		
	}

	@Override
	public boolean checkCronValid(String cronExpression) {
		boolean valid = CronUtils.isValid(cronExpression);
		return valid;
	}

	@Override
	public void startAllJobs() throws SchedulerException {
		TwbQuartzJob param = new TwbQuartzJob();
		param.setIsdel(0);
//		param.setStatus(QuartzConstants.Status.NORMAL.getValue());
		List<TwbQuartzJob> list = this.list(param);
		for (TwbQuartzJob job : list) {
			ScheduleUtils.createScheduleJob(scheduler, job);
		}
	}
}
